ποΈGitΠ―ΡΠ°ποΈ
.skills/compose-ui/SKILL.md claude/compass-waituntil-timeout (301aa418) Text, 4.98 KB
Skill: Compose Multiplatform (CMP) UI
Description
Guidelines for building shared UI, adaptive layouts, and handling strings/resources in Meshtastic-Android. The codebase uses Material 3 Adaptive.
1. UI Components & Layouts
β’ Material 3 / Adaptive: Use T383838currentWindowAdaptiveInfo(supportLargeAndXLargeWidth = true) to support Large (1200dp) and XL (1600dp) breakpoints. Investigate 3-pane "Power User" scenes using Navigation 3 Scenes and draggable dividers for desktopApp/tablets.
β’ Dialogs & Alerts: Use centralized components like T383838AlertHost(alertManager) from T383838core:ui/commonMain. Do NOT trigger alerts inline or duplicate alert logic. Use T383838SharedDialogs(uiViewModel) for general popups.
β’ Placeholders: Use T383838PlaceholderScreen(name) from T383838core:ui/commonMain for unimplemented desktopApp/JVM features.
β’ Theme Picker: Use T383838ThemePickerDialog from T383838feature:settings/commonMain.
β’ Platform Implementations: Inject platform-specific behavior (e.g., Map providers) via T383838CompositionLocal from the T383838app or T383838desktop shells. Do not tightly couple Google Maps/osmdroid dependencies to T383838commonMain.
2. Strings & Resources
β’ Multiplatform Resources: MUST use T383838core:resources (e.g., T383838stringResource(Res.string.your_key)). Never use hardcoded strings.
β’ ViewModels/Coroutines: Use the asynchronous T383838getStringSuspend(Res.string.your_key). NEVER use blocking T383838getString() in a coroutine context.
β’ Formatting Constraints: CMP T383838stringResource only supports T383838%N$s (string) and T383838%N$d (integer).
β’ No Float formatting: Formats like T383838%N$.1f pass through unsubstituted. Pre-format in Kotlin using T383838NumberFormatter.format(value, decimalPlaces) from T383838core:common and pass as a string argument (T383838%N$s):
T282828
Tff7b72val Te6edf3formatted Tff7b72= Te6edf3NumberFormatterTb4b4b4.Te6edf3formatTb4b4b4(Te6edf3batteryLevelTb4b4b4, T79c0ff1Tb4b4b4) T8b949e// "73.5"
Te6edf3stringResourceTb4b4b4(Te6edf3ResTb4b4b4.Te6edf3stringTb4b4b4.Te6edf3battery_percentTb4b4b4, Te6edf3formattedTb4b4b4) T8b949e// uses %1$s
β’ Percent Literals: Use bare T383838% (not T383838%%) for literal percent signs in CMP-consumed strings.
String Formatting Decision Tree
Choose the right tool for the job:
βββββββββββββββββββββββββββββββββββββββββββ¬βββββββββββββββββββββββββββββββββββββββββββββββββββ¬ββββββ
β Scenario β Tool β Exβ¦ β
βββββββββββββββββββββββββββββββββββββββββββΌβββββββββββββββββββββββββββββββββββββββββββββββββββΌββββββ€
β Metric display (temp, voltage, %, signβ¦ β T383838MetricFormatter.* β T383838Meβ¦ β
β Simple number + unit β T383838NumberFormatter + interpolation β T383838"$β¦ β
β Localized template from strings.xml β T383838stringResource(Res.string.key, preFormattedArgs) β T383838stβ¦ β
β Non-composable template (notificationsβ¦ β T383838formatString(template, args) β T383838foβ¦ β
β Hex formatting β T383838formatString β T383838foβ¦ β
β Date/time β T383838DateFormatter β T383838Daβ¦ β
βββββββββββββββββββββββββββββββββββββββββββ΄βββββββββββββββββββββββββββββββββββββββββββββββββββ΄ββββββ
Rules:
1. NEVER use T383838%.Nf in strings.xml β CMP cannot substitute them. Use T383838%N$s and pre-format floats.
2. Prefer T383838MetricFormatter over scattered T383838formatString("%.1fΒ°C", temp) calls.
3. T383838formatString (pure Kotlin) is a pure-Kotlin T383838commonMain implementation for: hex formats, multi-arg templates fetched at runtime, and chart axis formatters. Located in T383838core:common T383838Formatter.kt.
4. T383838NumberFormatter always uses T383838. as decimal separator β intentional for mesh networking precision.
β’ Workflow to Add a String:
1. Add to T383838core/resources/src/commonMain/composeResources/values/strings.xml.
2. Run T383838python3 scripts/sort-strings.py β keeps the file sorted and regenerates T383838strings-index.txt.
3. Use the generated T383838org.meshtastic.core.resources.<key> symbol.
4. Validate UI presentation.
3. Tooling & Capabilities
β’ Image Loading: Use T383838libs.coil (Coil Compose) in feature modules. Configuration/Networking for Coil (T383838coil-network-ktor3) happens strictly in the T383838app and T383838desktop host modules.
β’ QR Codes: Use T383838rememberQrCodePainter from T383838core:ui/commonMain powered by T383838qrcode-kotlin. No ZXing or Android Bitmap APIs in shared code.
4. Compose Previews
β’ Preview in commonMain: CMP 1.11+ supports T383838@Preview in T383838commonMain via T383838compose-multiplatform-ui-tooling-preview. Place preview functions alongside their composables.
β’ Import: Use T383838androidx.compose.ui.tooling.preview.Preview. The JetBrains-prefixed import (T383838org.jetbrains.compose.ui.tooling.preview.Preview) is deprecated.
5. Dialog & State Patterns
β’ Dialog State Preservation: Use T383838rememberSaveable for dialog state (search queries, selected tabs, expanded flags) to preserve across configuration changes. Boolean and String types are auto-saveable β no custom T383838Saver needed.
Reference Anchors
β’ Shared Strings: T383838core/resources/src/commonMain/composeResources/values/strings.xml
β’ Platform abstraction contract: T383838core/ui/src/commonMain/kotlin/org/meshtastic/core/ui/util/MapViewProvider.kt
β’ Provider wiring: T383838androidApp/src/main/kotlin/org/meshtastic/app/MainActivity.kt
Served by rngit 1.5.2 - Generated in 0.05s